package com.demo.spring.componentScan;

import java.io.IOException;

import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.stereotype.Component;

import com.demo.spring.componentScan.demo1.Student;

public class 自定义实现ComponentScan {
	
	public static void main(String[] args) throws Exception {
		GenericApplicationContext context = new GenericApplicationContext();
		context.registerBeanDefinition("student", new AnnotatedGenericBeanDefinition(Student.class));
		
		// 手动实现ComponentScan
		ComponentScan componentScan = AnnotationUtils.findAnnotation(Student.class, ComponentScan.class);
		AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
		for(String p : componentScan.basePackages()) {
			String path = "classpath*:" + p.replace(".", "/") + "/**/*.class";
			CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
			Resource[] resources = context.getResources(path);
			for (Resource resource : resources) {
				MetadataReader reader = factory.getMetadataReader(resource);
				System.out.println("类名：" + reader.getClassMetadata().getClassName());
				AnnotationMetadata annotationMetadata = reader.getAnnotationMetadata();
				System.out.println("是否加了@Component：" + annotationMetadata.hasAnnotation(Component.class.getName()));
				System.out.println("是否加了@Component 派生：" + annotationMetadata.hasMetaAnnotation(Component.class.getName()));
				
				if(annotationMetadata.hasAnnotation(Component.class.getName()) ||
						annotationMetadata.hasMetaAnnotation(Component.class.getName())) {
					AbstractBeanDefinition bd = BeanDefinitionBuilder
							.genericBeanDefinition(reader.getClassMetadata().getClassName())
							.getBeanDefinition();
					String beanName = generator.generateBeanName(bd, context.getDefaultListableBeanFactory());
					context.getDefaultListableBeanFactory().registerBeanDefinition(beanName, bd);
				}
			}
		}
		
		context.refresh();
		for(String name : context.getBeanDefinitionNames()) {
			System.out.println(name);
		}
	}

}
